package com.ybt.communicate.tcp.factory;

import com.ybt.communicate.core.IProtocol;
import com.ybt.communicate.core.configration.IProtocolConstants;
import com.ybt.communicate.core.exception.ProtocolException;
import com.ybt.communicate.core.factory.IProtocolFactory;
import com.ybt.communicate.tcp.accessor.IDataAccessStrategy;
import com.ybt.communicate.tcp.accessor.factory.DataAccessFactory;
import com.ybt.communicate.tcp.client.TCPClientLong;
import com.ybt.communicate.tcp.client.TCPClientShort;
import com.ybt.communicate.tcp.configration.TCPConstants;
import com.ybt.communicate.tcp.configration.TCPProtocolConfig;
import com.ybt.communicate.tcp.configration.TCPRuntimeConfig;
import com.ybt.communicate.tcp.server.TCPServerLong;
import com.ybt.communicate.tcp.server.TCPServerShort;

public class TCPProtocolFactory implements IProtocolFactory<TCPProtocolConfig> {

    public IProtocol createProtocol(TCPProtocolConfig protocolConfig)
            throws ProtocolException {
        // TODO Auto-generated method stub
        TCPRuntimeConfig rconfig = new TCPRuntimeConfig(protocolConfig);
        if (TCPConstants.LONG_CONNECTOR.equals(protocolConfig
                .getCommonConfig().getType())) {
            //长连接
            rconfig.setLongMode(true);
        }
        //端口
        int port = protocolConfig.getCommonConfig().getPort();
        rconfig.setPort(port);
        //缓冲池、转发线程数
        int workThread = protocolConfig.getCommonConfig()
        .getWorkingThread();
        rconfig.setWorkThread(workThread);

        IProtocol protocol = null;
        if (protocolConfig.isServerSide()) {
            // 作为服务器接收数据使用
            if (IProtocolConstants.MODE_DUPLEX.equals(protocolConfig
                    .getProtocolMode())) {
                // tcp 双工同步协议
                rconfig.setDuplex(true);
                IDataAccessStrategy acc = DataAccessFactory.createDataAccess(
                        protocolConfig.getCommonConfig().getStrategy(),
                        protocolConfig.getCommonConfig().getEncode());
                rconfig.setReadAccessor(acc);
                //FIXME 暂时读写策略一直
                rconfig.setWriteAccessor(acc);
            } else {
                // TCP单工异步协议
                rconfig.setDuplex(false);
                rconfig.setReadAccessor(DataAccessFactory.createDataAccess(
                        protocolConfig.getCommonConfig().getStrategy(),
                        protocolConfig.getCommonConfig().getEncode()));
            }
            //初始化协议
            if(rconfig.isLongMode()){
                //长连接
                protocol = new TCPServerLong(rconfig);
            }else{
                //短连接
                protocol = new TCPServerShort(rconfig);
            }
        } else {
            // 作为客户端发送数据使用
            //ip
            String host = protocolConfig.getCommonConfig().getHost();
            rconfig.setIp(host);

            if (IProtocolConstants.MODE_DUPLEX.equals(protocolConfig
                    .getProtocolMode())) {
                // tcp双工同步协议
                rconfig.setDuplex(true);
                //取request配置的读取策略
                IDataAccessStrategy acc = DataAccessFactory.createDataAccess(
                        protocolConfig.getCommonConfig().getStrategy(),
                        protocolConfig.getCommonConfig().getEncode());
                rconfig.setReadAccessor(acc);
                rconfig.setWriteAccessor(acc);
            } else {
                // TCP单工异步协议，只用于发送数据
                rconfig.setDuplex(false);
                rconfig.setWriteAccessor(DataAccessFactory.createDataAccess(
                        protocolConfig.getCommonConfig().getStrategy(),
                        protocolConfig.getCommonConfig().getEncode()));
            }
            
            //初始化协议
            if(rconfig.isLongMode()){
                //长连接
                protocol = new TCPClientLong(rconfig);
            }else{
                //短连接
                protocol = new TCPClientShort(rconfig);
            }
        }
        return protocol;
    }

}
